using Furion;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;

namespace Magic.Core
{
    /// <summary>
    /// 分页拓展类
    /// </summary>
    public static class PagedQueryableExtensions
    {
        private static Expression RightContainsLeft(this Expression expression, ParameterExpression param, PropertyInfo property,List<long> list)
        {
            if (property != null)
            {
                var left = Expression.Property(param, property);

                if (property.PropertyType == typeof(Nullable<long>))
                {
                    expression = Expression.Call(Expression.Constant(list.ToJsonString().ToObject<List<long?>>()), typeof(List<Nullable<long>>).GetMethod("Contains", new Type[] { typeof(Nullable<long>) }),
                                left);
                }
                else if (property.PropertyType == typeof(long))
                {
                    expression = Expression.Call(Expression.Constant(list), typeof(List<long>).GetMethod("Contains", new Type[] { typeof(long) }),
                        left);
                }
                else
                {
                    expression = Expression.Call(Expression.Constant(list), typeof(List<string>).GetMethod("Contains", new Type[] { typeof(string) }),
                        left);
                }
            }
            return expression;
        }
        /// <summary>
        /// 数据过滤
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="field">需要过滤的用户id字段,CloseDataFilter关闭过滤</param>
        /// <returns></returns>
        public static async Task<ISugarQueryable<TEntity>> ToDataFilter<TEntity>(this ISugarQueryable<TEntity> entity, string field = "")
        {
            var _scopeFactory = App.GetService<IServiceScopeFactory>();
            var query = entity;
            using (var scope= _scopeFactory.CreateScope())
			{
                var service = scope.ServiceProvider;
                var _sysUserService = App.GetService<Service.ISysUserService>(service);
                Expression expression = null;
                var param = Expression.Parameter(typeof(TEntity), "a");
                var dataScopes = await _sysUserService.GetDataScopeIdUserList(UserManager.UserId);
                if (!UserManager.IsSuperAdmin && field != "CloseDataFilter")
                {
                    if (string.IsNullOrEmpty(field))
                    {
                        PropertyInfo property = typeof(TEntity).GetProperty("CreatedUserId");
                        if (property != null)
                        {
                            expression = expression.RightContainsLeft(param, property, dataScopes);
                        }
                    }
                    else
                    {
                        PropertyInfo property = typeof(TEntity).GetProperty(field);
                        if (property != null)
                        {
                            expression = expression.RightContainsLeft(param, property, dataScopes);
                        }
                    }
                }
                if (expression != null && UserManager.UserId > 0)
                {
                    query = query.MergeTable().Where((Expression<Func<TEntity, bool>>)Expression.Lambda(expression, param));
                }
            }
            return query;
        }

        /// <summary>
        /// 分页拓展
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="field">需要过滤的用户id字段,CloseDataFilter关闭过滤</param>
        /// <returns></returns>
        public static async Task<SqlSugarPagedList<TEntity>> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> entity, int pageIndex, int pageSize, string field = "")
        {
            RefAsync<int> totalCount = 0;
            var query = await entity.ToDataFilter(field);
            var items = await query .ToPageListAsync(pageIndex, pageSize, totalCount);
            var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
            return new SqlSugarPagedList<TEntity>
            {
                PageIndex = pageIndex,
                PageSize = pageSize,
                Items = items,
                TotalCount = (int)totalCount,
                TotalPages = totalPages,
                HasNextPages = pageIndex < totalPages,
                HasPrevPages = pageIndex - 1 > 0
            };
        }
    }
}